package com.example.infrastructure.domain.organization.repo.impl;

import com.example.infrastructure.domain.organization.aggregate.Organization;
import com.example.infrastructure.domain.organization.repo.OrganizationRepo;
import com.example.infrastructure.domain.organization.repo.dao.OrganizationDao;
import com.example.infrastructure.domain.organization.repo.po.OrganizationPo;
import com.example.infrastructure.infrastructure.mapper.CycleAvoidingMappingContext;
import com.example.infrastructure.infrastructure.mapper.organization.OrganizationMapper;
import org.springframework.data.domain.Example;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author lxh
 * @date 2020/11/17 下午1:32
 **/
@Repository
public class OrganizationRepoImpl implements OrganizationRepo {
    private final OrganizationDao organizationDao;

    public OrganizationRepoImpl(OrganizationDao organizationDao) {
        this.organizationDao = organizationDao;
    }

    private static Organization toDo(OrganizationPo po) {
        return OrganizationMapper.INSTANCE.toDo(po, new CycleAvoidingMappingContext());
    }

    private static OrganizationPo toPo(Organization organization) {
        return OrganizationMapper.INSTANCE.toPo(organization);
    }

    private static Example<OrganizationPo> toExample(Example<Organization> example) {
        return Example.of(toPo(example.getProbe()), example.getMatcher());
    }

    @Override
    public Optional<Organization> findOne(Example<Organization> example) {
        Optional<OrganizationPo> organizationPo = organizationDao.findOne(toExample(example));
        return organizationPo.map(OrganizationRepoImpl::toDo);
    }

    @Override
    public List<Organization> findAllByExample(Example<Organization> example) {
        List<OrganizationPo> poList = organizationDao.findAll(toExample(example));
        return poList.stream().map(OrganizationRepoImpl::toDo).collect(Collectors.toList());
    }

    @Override
    public List<Organization> findAllBySpecification(Specification<OrganizationPo> specification) {
        List<OrganizationPo> poList = organizationDao.findAll(specification);
        return poList.stream().map(OrganizationRepoImpl::toDo).collect(Collectors.toList());
    }

    @Override
    public Organization save(Organization organization) {
        return toDo(organizationDao.save(toPo(organization)));
    }

    @Override
    public void deleteById(String id) {
        organizationDao.deleteById(id);
    }

    @Override
    public void delete(Organization organization) {
        organizationDao.delete(toPo(organization));
    }
}
